#include "UDPSocket.h"
#include <cstdio>

UDPSocket::UDPSocket()
{
        mIsInitialOK = false;
}


UDPSocket::~UDPSocket()
{
}


UDPSocket & UDPSocket::instance()
{
    static UDPSocket udp_socket;
    return udp_socket;
}


void UDPSocket::Initial(const char *host, int port)
{
        struct hostent *host_ent ;
        struct in_addr *addr_ptr ;

        if ((host_ent = (struct hostent *)gethostbyname(host)) == 0)
        {
                if (inet_addr(host) == INADDR_NONE)
                        printf("Invalid host name");
        }
        else
        {
                addr_ptr = (struct in_addr *) *host_ent->h_addr_list ;
                host = inet_ntoa(*addr_ptr) ;
        }

        if( (mSockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        {
                printf("Can't create socket") ;
        }

        memset(&mAddress, 0, sizeof(mAddress)) ;
        mAddress.sin_family         = AF_INET ;
        mAddress.sin_addr.s_addr    = htonl(INADDR_ANY) ;
        mAddress.sin_port           = htons(0) ;

        if(bind(mSockfd, (sockaddr *)&mAddress, sizeof(mAddress)) < 0)
        {
                close(mSockfd);
                printf("Can't bind client to any port") ;
        }

        memset(&mAddress, 0, sizeof(mAddress)) ;
        mAddress.sin_family         = AF_INET ;
        mAddress.sin_addr.s_addr    = inet_addr( host ) ;
        mAddress.sin_port           = htons( port ) ;
        mIsInitialOK                = true;
}


int UDPSocket::Receive(char *msg)
{
        socklen_t servlen ;

        sockaddr_in serv_addr;
        servlen = sizeof(serv_addr);
        int n = recvfrom(mSockfd, msg, MAX_MESSAGE, 0, (sockaddr *)&serv_addr, &servlen);
        if (n > 0)
        {
                msg[n] = '\0' ; // rccparser will crash if msg has no end
                mAddress.sin_port = serv_addr.sin_port ;
        }

        //printf("Received command %s", msg);

        return n;
}


int UDPSocket::Send(const char *msg)
{
        //printf("Sending command %s\n", msg);
        if (mIsInitialOK == true)
        {
                int n = std::strlen(msg) ;
                n = sendto(mSockfd, msg, n+1, 0, (sockaddr *)&mAddress, sizeof(mAddress));
                return n;
        }

        std::cout << msg << std::endl;
        return std::strlen(msg);
}

